home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-01-19 | 58.8 KB | 1,134 lines |
- .MT2
- .MB0
- .PO0
- .PN0
- Virtual Control Program Interface
-
- Version 1.0
- June 12, 1989
-
- VCPI SPONSORS
-
- A.I. Architects, Inc., Peabody, MA
- Lotus Development Corp., Cambridge, MA
- Phar Lap Software, Inc., Cambridge, MA
- Quadram, Norcross, GA
- Qualitas, Inc., Bethesda, MD
- Quarterdeck Office Systems, Santa Monica, CA
- Rational Systems, Inc., Natick, MA
-
- VCPI Co-ordinators: Phar Lap Software, Inc.
- (617) 661-1510
- Robert Moote
-
- Quarterdeck Office Systems
- (310) 392-9851
- Daniel Spear
-
- Copyright Phar Lap Software, Inc., 1987-1989
- Copyright Quarterdeck Office Systems, 1987-1989
-
- This specification may be duplicated provided it is reproduced in its
- entirety, including the above copyright notice.
-
-
-
-
- Version 1.0 Specification Revision History
-
- June 12, 1989 Final revision approved by attendees of the VCPI
- Developer's Conference, held at the offices of Phar
- Lap Software on April 25, 1989. Attendees included
- the following VCPI sponsors: A.I. Architects,
- Inc., Lotus Development Corporation, Phar Lap
- Software, Inc., Qualitas, Inc., Quarterdeck Office
- Systems, Rational Systems, Inc.; and the following
- observers: Compaq Computer Corporation, Intel
- Corporation.
-
- May 8, 1989 Revision incorporating modifications agreed upon at
- the VCPI Developer's Conference. This revision was
- distributed for approval to all conference
- attendees.
-
- March 31, 1989 A more detailed and explicit revision of the
- December 1987 specification, drafted for review at
- the VCPI Developer's Conference.
-
- December 21, 1987 First revision of the specification, written by
- Phar Lap Software, Inc., and Quarterdeck Office
- Systems.
-
-
- 1.0 Background
-
- The Intel 80386 microprocessor has three fundamental operating modes. Real
- mode is provided for backward compatibility with existing 8086 programs.
- Protected mode allows programs written specifically for the 80386 to take
- advantage of the larger address space available. Virtual 8086 (V86) mode,
- like real mode, is used to run 8086 programs. However, V86 mode runs under
- the control of a protected mode operating environment. This provides certain
- advantages, chiefly the ability to enable the paging hardware of the 80386 and
- thus run multiple 8086 programs simultaneously, and also the ability to make
- arbitrary physical memory available within the V86 address space of an 8086
- program. (The 80486 microprocessor provides the same architecture and
- operating modes as the 80386, thus software written for the 80386 runs without
- modification on an 80486).
-
- The capabilities of the 8086 have spawned the creation of several new kinds of
- control programs that can run under MS-DOS on a 386 machine. To date, these
- programs fall into three basic categories: (1) protected mode run-time
- environments, which allow an application program to execute in protected mode
- under MS-DOS; (2) EMS emulators, which use V86 mode to make all the memory on
- the machine available to 8086 programs which use EMS (Lotus/Intel/Microsoft
- Expanded Memory Specification) memory, and, (3) multitasking environments
- which use V86 mode to multitask 8086 MS-DOS programs, while still giving each
- 8086 program a full 640Kb of physical memory (or more, if they use EMS
- memory). Such multitasking environments typically run in conjunction with a
- separate EMS emulator, or implement the EMS interface as part of the
- multitasker. For the remainder of this specification, the terms "DOS-
- Extender," "EMS emulator," and "multitasker," respectively, will be used to
- refer to these program categories.
-
- Since these control programs run under MS-DOS, it is desirable to make them
- compatible with each other, so that users don't have to turn off one control
- program in order to run an application under another control program. The
- purpose of this document is to specify an interface that allows these classes
- of control programs to coexist successfully. This interface is called the
- Virtual Control Program Interface, or VCPI.
-
- 2.0 Areas of Conflict
-
- There are a variety of resource contention issues which must be solved to
- allow multiple 386 control programs to coexist. The section below summarizes
- each of these issues.
-
- 2.1 Extended Memory Allocation
-
- Because DOS only knows about memory below one MB, there is no universally used
- method in the DOS environment for allocating and freeing extended memory
- (memory above one MB). The following existing techniques are available for
- allocating extended memory on both 80286 and 80386 PCs:
-
- 1. Memory can be allocated "top down" by taking over the BIOS extended
- memory size system call (INT 15h function 88h) and reporting less
- extended memory available than is actually present on the machine.
- This method allocates a contiguous block of memory starting at the top
- of extended memory and growing downward. See Appendix A.1 for a
- description of top down allocation.
-
- 2. Memory can be allocated "bottom-up" by taking over the PC reboot
- interrupt (INT 19h) and installing a signature block and allocation
- size marker in the interrupt handler, and boot block with an
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 1
-
- allocation size marker at one megabyte. This is commonly referred to
- as the VDISK technique, since it is the method employed by the
- original IBM VDISK driver. This method allocates a contiguous block
- of memory starting at one megabyte and growing upward. See Appendix
- A.2 for a description of bottom-up allocation.
-
- 3. If an XMS (Microsoft Extended Memory Specification) drive is
- installed, extended memory can be allocated by making calls to the XMS
- driver. The XMS driver reserves extended memory for an XMS memory
- pool using top-down allocation, and the allocates memory out of the
- XMS memory pool. Copies of the XMS specification may be obtained by
- calling Microsoft at 1-800-426-9400.
-
- A program that wishes to allocate extended memory must first determine what
- extended memory is free (not in use by another program). It does this by
- calling INT 15h function 88h to obtain the top of free extended memory, and by
- checking the signature of INT 19h and the boot block at one megabyte for any
- bottom-up memory allocation, thus obtaining the bottom of free extended
- memory.
-
- The program can then allocate its own chunk of extended memory, either top
- down by taking over INT 15h, or bottom-up by taking over INT 19h. The top-down
- allocation method is preferable because it is simpler and more robust. The
- diagram below shows an example in which three programs which use extended
- memory are installed. Program 1 (the first program installed) allocates some
- extended memory bottom-up, program 2 allocates two chunks of memory, one
- bottom-up and one top-down, and program 3 allocates memory top-down.
-
- top of _______________________________
- memory |XXXXXXXXXXXXXXXXXXXXXXXXXXX|<= allocated by program 2
- |XXXXXXXXXXXXXXXXXXXXXXXXXXX|
- |---------------------------|--
- |***************************|<= allocated by program 3
- |---------------------------|--
- | |<= free extended memory
- |---------------------------|--
- |XXXXXXXXXXXXXXXXXXXXXXXXXXX|<= allocated by program 2
- |XXXXXXXXXXXXXXXXXXXXXXXXXXX|
- |---------------------------|--
- |^^^^^^^^^^^^^^^^^^^^^^^^^^^|<= allocated by program 1
- 1 MB => |---------------------------|--
- |///////////////////////////|<= BIOS ROM, screen, etc.
- 640 KB => |---------------------------|--
- |\\\\\\\\\\\\\\\\\\\\\\\\\\\|<= DOS memory
- |___________________________|__
-
- Note that only the last installed program which allocates extended memory top-
- down or bottom-up (the first program in the interrupt chain for INT 15h or INT
- 19h) can dynamically change its memory allocation. In the example above, only
- program 2 can dynamically modify its bottom-up memory allocation, and only
- program 3 can dynamically modify its top-down memory allocation.
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 2
-
- It is possible for VCPI memory, XMS memory and extended memory all to be
- available on a single PC. (This can occur, for example, if a VCPI driver is
- installed and is given a portion of extended memory, an XMS driver is
- installed and even another chunk of extended memory, and the rest of extended
- memory is left free.) Therefore, programs which can use extended memory may
- wish to look for all three sources of memory. The recommended order of use of
- the different memory allocation methods is: (1) VCPI memory, (2) XMS memory,
- and, (3) extended memory.
-
- 2.2 Mode Switching
-
- All 386 control programs need to do some processing in protected mode, but
- also need to allow standard 8086 code (such as other applications, DOS, and
- the BIOS) to execute. Therefore, they must switch between 80386 protected mode
- and either real mode or V86 mode.
-
- If two control programs both switch between protected mode and real mode, no
- special problems are posed. If, however, a control program switches between
- V86 mode and protected mode, it is impossible for a second control program to
- switch into protected mode. This is because programs running in V86 mode are
- executing at the least privileged level of the 80386 processor, so system-
- level operations will cause processor exceptions, which result in the first
- control program regaining control. Thus the first control program must
- provide a method to allow subsequent control programs to switch to protected
- mode and back to V86 mode again.
-
- 2.3 8259A Interrupt Controller
-
- The standard interrupt vectors used on the 386 PC for hardware interrupts
- IRQ0 - IRQ7 are vectors 08h - 0Fh. Unfortunately, those vectors are also used
- by the 80386 processor for certain processor exceptions. For this reason,
- some 386 control programs reprogram the 8259A interrupt controller chip to
- relocate IRQ0 - IRQ7 to different interrupt vectors. Information about
- reprogramming of the 8259A must be made available to all cooperating 386
- control programs.
-
- 2.4 Privileged Instructions
-
- When the 386 processor is executing in V86 mode, it is executing at privilege
- level 3 (the least privileged level), and privileged instructions cause an
- exception. These include instructions which load or store 386 system
- registers, including the control registers, the debug registers, the test
- registers, GDTR, LDTR, and TR. Access to some of these registers is needed in
- V86 mode; others only need to be modified as part of a mode switch to
- protected mode.
-
- In addition, a number of instructions cause a general protection exception if
- the I/O privilege level (IOPL) is not 3 when executing in V86 mode. These
- instructions must be made available, either by setting IOPL to 3, or by
- emulating the instructions.
-
- 3.0 Interface Summary
-
- Many of the problems listed above occur only when one control program uses V86
- mode. EMS emulators run in V86 mode and are widely used on 386 PCs, and an
- EMS interface is typically used or provided by multitaskers. In addition, one
- of the primary functions performed by EMS emulators is memory allocation.
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 3
-
- For these reasons, the VCPI interface is defined as a superset of the EMS
- version 4.0 interface (an EMS 4.0 driver must be provided underneath the VCPI
- interface; a copy of the EMS 4.0 interface specification may be obtained by
- calling Intel literature sales at 1-800-548-4725 and requesting part #300275).
- If an EMS emulator with the VCPI interface is installed, a multitasker and/or
- an arbitrary number of DOS-Extender programs which use the VCPI interface can
- be run. Control programs which utilize the VCPI interface provided by the EMS
- emulator will be referred to as "clients" for the remainder of this document.
- The control program providing the VCPI interface (and the EMS 4.0 interface)
- will be referred to as the "server" for the remainder of this document.
-
- A server is installed at boot time, and takes over a block of extended memory
- which becomes the expanded memory pool from which it allocates EMS pages.
- When the server is installed, it can be given all the extended memory on the
- computer, or extended memory can be "partitioned" into expanded memory and
- extended memory (i.e., some extended memory is taken by the server for the
- expanded memory pool, and the rest is left free, available for use by other
- programs).
-
- Clients can obtain memory by making requests of the server. Memory allocated
- though the VCPI interface comes out of the memory pool owned by the server
- (i.e., expanded memory), and must be in the physical address space of the
- computer (e.g., it must not be memory on a separate expanded memory board).
- If any extended memory is left free by the server, clients can allocate that
- extended memory in the usual way.
-
- The VCPI interface is implemented with calls to functions provided by the
- server. Calls need to be made both in V86 mode and in protected mode. The
- V86 mode calls are implemented through the standard INT 67h EMS interface.
- The protected mode calls are made with FAR procedure calls to an entry point
- in the server. The protected mode entry point is obtained via an
- initialization on call to the server.
-
- Both the server and each client program maintain their own set of system
- tables (GDT, LDT, IDT, page tables, etc.) Each client program must initialize
- a memory space in its page tables which is identical to a portion of the
- memory space used by the server, in order to provide a common ground for
- communication with the server. When the client calls the server to switch to
- protected mode, the client's system tables are set up as part of the mode
- switch. Likewise, when the client calls the server to switch back to V86
- mode, the server's system tables are set up.
-
- The server must leave A20 (address line 20 on a PC) enabled at all times, in
- both V86 mode and in protected mode.
-
- The client must always use the services of the server to switch modes. It
- should never, for example, implement its own switch back to V86 mode, because
- the server's system tables must be set up when executing in V86 mode.
-
- 4.0 V86 Mode Program Interface
-
- The V86 mode interface is provided through the EMS interrupt (INT 67h), with
- an EMS function code in AH of DEh, and a VCPI function code in AL. (Note that
- any EMS driver which does not provide VCPI should return either code 84h (bad
- function code) for this EMS call, since it is not a defined function number
- for the LIM 4.0 EMS specification.) If the function succeeds, AH is returned
- as zero; otherwise, there is an error code in AH. Except as noted for each
- call, all other registers are unchanged on output.
-
- _______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 4
-
- If an undefined VCPI subfunction code is passed in AL, the server returns an
- either code in AH; the recommended value is 8Fh (bad subfunction code).
-
- The IOPL-sensitive privileged instructions must be available in V86 mode.
- This means the server must either set the IOPL to 3, or emulate these
- instructions. Other privileged instructions need not be emulated as part of
- the VCPI interface. Instead, access to certain system registers is provided
- via system calls (see Section 4.4).
-
- 4.1 Presence Detection
-
- The presence of a server which provides the VCPI interface is detected by
- first using one of the standard detection checks to see if an EMS driver is
- installed, and then making the EMS call below to check for the presence of
- VCPI.
-
- ==============================================================================
- INT 67h
- AX = DE00h VCPI Presence Detection
- ==============================================================================
- INPUTS: None
- -------------------------------------------------------------------------------
- OUTPUTS: If VCPI is present:
- AH = 0
- BL = 0 (VCPI minor version number, in binary)
- BH = 1 (VCPI major version number, in binary)
- If not present:
- AH = nonzero (recommended value: 84h)
- -------------------------------------------------------------------------------
-
- If the server is installed but no EMS memory has been allocated, the server
- may be executing in real mode rather than V86 mode. The detection call should
- return success in real mode as well as V86 mode (so that it is possible to
- detect a VCPI server that is currently turned off, and also for backward
- compatibility with clients that make this call in real mode); however, for the
- rest of the VCPI interface to be enabled, the processor must be executing in
- V86 mode. Therefore, the following VCPI detection sequence is recommended:
-
- 1. Check to see if the processor is an 80386 or 80486.
- 2. Check to see if an EMS driver is installed.
- 3. Allocate one EMS page. This will turn on the EMS driver if it is
- off, switching the processor to V86 mode.
- 4. Make the above VCPI detection call.
-
- The EMS page allocated in step 3 must not be deallocated again until the
- client is done using the VCPI interface; otherwise, the server could turn off
- again, setting the processor back to real mode and disabling the VCPI
- interface.
-
- Appendix A.3 contains a code sequence demonstrating VCPI detection.
-
- 4.2 Interface Initialization
-
- The interface initialization process involves creating a common ground between
- the server and the client that allows them to communicate in protected mode,
- and providing any other information that the client may need to complete its
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 5
-
- own initialization. Since the server and the client each have separate page
- tables, GDT, LDT, and IDT, in order to communicate in protected mode the
- client must set up a region in its page tables that maps memory used by the
- server, and must initialize segment descriptors in its GDT to point to code
- and data regions in the server.
-
- The calls below are used to initialize the interface between the server and
- the client.
-
- ==============================================================================
- INT 67h
- AX = DE01h Get Protected Mode Interface
- ==============================================================================
- INPUTS: ES:DI = pointer to 4K page table buffer
- DS:SI = pointer to three descriptor table entries in the
- client's GDT, the first to be set up as the
- protected mode code segment in the server, and the
- additional two entries to be used as desired by
- the server when it is called in protected mode
- -------------------------------------------------------------------------------
- OUTPUTS: AH = 0
- DI = advanced to point to the first unused page table
- entry in the buffer (could be advanced by 4K, if
- server initializes entire page table)
- EBX = offset in code segment of protected mode entry point
- -------------------------------------------------------------------------------
-
- The Get Protected Mode Interface call is used to set up a common frame of
- reference which allows the client to make calls to the server in protected
- mode. The call initializes a page table which the client must set up as its
- 0th page table. This page table must map at least one megabyte of memory
- starting at linear address zero: the real mode address space provided in V86
- mode. In addition, the server can map any additional memory above one
- megabyte (up to a total of four megabytes, since there is just one page table)
- which it requires to provide the protected mode interface. While the mappings
- for the first megabyte must be identical for both the client and the server
- (so the client will be able to set up segments to access its V86 memory from
- protected mode), memory above one megabyte can be mapped as desired by the
- server (e.g., if the server's code and data is mapped at a high address in its
- own page tables, it would simply map the same code and data just above one
- megabyte in the client's 0th page table).
-
- For backward compatibility, both the server and the client must clear the
- software-defined bits (bits 9 - 11) in the page table entries it copies into
- the client's page table; all other bits should be preserved the client must
- not copy its 0th page table to a different physical page after this call is
- made. This is so the server can always access the client's 0th page table.
- The client must never modify any bits other than the software-defined bits (9-
- 11) in the page table entries which are initialized by this call.
-
- In addition to initializing the 0th page table, this call also fills in a GDT
- entry in the client's GDT. This segment is used by the client when calling
- the server in protected mode. The segment must be set up as a code segment,
- and must reside in the linear address space set up in the 0th page table by
- this call. The entry point of the interface routine (its offset within the
- code segment) is returned in EBX. Two additional entries in the client's GDT,
- immediately following the GDT entry for the code segment, are available to the
- server for its own use. Typically at least one of these GDT segments is used
- by the server as a data segment.
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 6
-
- When the client calls the server in protected mode, it makes a FAR call to a
- USE32 segment, using the entry point provided by this call. Since the server
- has initialized the code segment descriptor, it can, of course, set it up any
- way it desires, but it is responsible for executing a USE32 FAR return when it
- terminates, regardless of the actual use type of the code segment. Thus, when
- the server is called in protected mode, it will have CS pointing to the code
- segment which is set up by this call. It can obtain selectors for the two
- additional GDT entries which it set up by adding 0008h and 0010h,
- respectively, to the segment selector value in CS. The server must preserve
- all segment registers across a protected mode VCPI call.
-
- ==============================================================================
- INT 67h
- AX = DE02h Get Maximum Physical Memory Address
- ==============================================================================
- INPUTS: None
- ------------------------------------------------------------------------------
- OUTPUTS: AH = 0
- EDX = PHYSICAL address of the highest 4K memory page that
- could ever be allocated.
- ------------------------------------------------------------------------------
-
- The Get Maximum Physical Memory Address call is used by the client to
- initialize its memory management data structures. To do this, it may need to
- know the physical address of the highest 4K memory page that could ever be
- allocated by the Allocate 4K Page call specified below. For backward
- compatibility, both the server and the client must mask the 12 LSBs of the
- physical page address (returned in EDX) to zero.
-
- 4.3 Memory Allocation Calls
-
- The memory allocation calls are used to allocate and free 4K pages of memory.
- The server allocates these pages out of its EMS memory pool. The client can
- also do its own allocation of extended memory or XMS memory, if any is
- available.
-
- ==============================================================================
- INT 67h
- AX = DE03h Get Number of Free 4K Pages
- ===============================================================================
- INPUTS: None
- -------------------------------------------------------------------------------
- OUTPUTS: AH = 0
- EDX = number of free 4K pages
- -------------------------------------------------------------------------------
-
- This call returns the total number of 4K pages available to be allocated out
- of the server's expanded memory pool.
-
- Note that this is the total amount of free memory available to all tasks on
- the system. The client should allocate this memory only on an as needed
- basis. In addition, in a multitasking environment, this number does not
- reflect any memory restrictions placed on the client task by the multitasker.
- The client should, during initialization, use the EMS call Get Number of Pages
- (INT 67h function 3 (AH=42h)) to obtain the number of unallocated EMS pages
- available, and then limit its usage of memory allocated through the server to
- that amount. (Note that the size of an EMS page is 16K, and the size of a
- page allocated through the VCPI interface is 4K.)
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 7
-
- ==============================================================================
- INT 67h
- AX = DE04h Allocate a 4K Page
- ===============================================================================
- INPUTS: None
- -------------------------------------------------------------------------------
- OUTPUTS: If success:
- AH = 0
- EDX = PHYSICAL address of allocated 4K page
- If failure:
- AH = nonzero (recommended value: 88h)
- EDX = contents modified
- -------------------------------------------------------------------------------
-
- This call allocates a 4K page of memory. For backward compatibility, both the
- server and client must make the 12 LSBs of the physical page address (returned
- in EDX) to zero. The client is responsible for freeing all memory allocated
- with this call before terminating execution.
-
- ==============================================================================
- INT 67h
- AX = DE05h Free a 4K Page
- ===============================================================================
- INPUTS: EDX = PHYSICAL address of 4K page to free
- -------------------------------------------------------------------------------
- OUTPUTS: If success:
- AH = 0
- If failure:
- AH = nonzero (recommended value: 8Ah)
- -------------------------------------------------------------------------------
-
- This call frees a page of memory previously allocated with subfunction 04h.
- For backward compatibility, both the server and the client must mask the 12
- LSBs of the physical page address (passed in EDX) to zero.
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 8
-
- ==============================================================================
- INT 67h
- AX = DE06h Get Physical Address of 4K Page in First Megabyte
- ===============================================================================
- INPUTS: CX = page number (linear address of page SHR 12)
- -------------------------------------------------------------------------------
- OUTPUTS: If success:
- AH = 0
- EDX = PHYSICAL address of 4K page
- If invalid page number:
- AH = nonzero (recommended value: 8Bh)
- -------------------------------------------------------------------------------
-
- This call returns the physical address of a 4K page in the first megabyte of
- the V86 mode linear address space. For backward compatibility, both the
- server and the client must mask the 12 LSBs of the physical page address
- (returned in EDX) to zero.
-
- This call is useful for obtaining the address of memory which is allocated and
- mapped into the first megabyte with the standard EMS calls. While this
- information can also be extracted from the page table obtained with the Get
- Protected Mode Interface system call, that page table is a "snapshot" of the
- server's page tables at the time the system call was made, and would not have
- the correct addresses for any EMS memory mapped in after the Get Protected
- Mode Interface call was made.
-
- 4.4 System Register Access Calls
-
- When executing in V86 mode, any attempt to load or store system registers
- causes a general protection exception. The system calls below provide access
- to certain system registers in V86 mode.
-
- ===============================================================================
- INT 67h
- AX = DE07h Read CR0
- ===============================================================================
- INPUTS: None
- -------------------------------------------------------------------------------
- OUTPUTS: AH = 0
- EBX = CR0 value
- -------------------------------------------------------------------------------
-
- This call returns the current value of the CR0 register.
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 9
-
- ===============================================================================
- INT 67h
- AX = DE08h Read Debug Registers
- ===============================================================================
- INPUTS: ES:DI = pointer to array of 8 DWORDS, DR0 first in
- array, DR4 and DR5 not used
- -------------------------------------------------------------------------------
- OUTPUTS: AH = 0
- -------------------------------------------------------------------------------
-
- This call stores the values of the debug registers into an array in memory.
-
-
- ===============================================================================
- INT 67h
- AX = DE09h Load Debug Registers
- ===============================================================================
- INPUTS: ES:DI = pointer to array of 8 DWORDS, DR0 first in array,
- DR4 and DR5 not used
- -------------------------------------------------------------------------------
- OUTPUTS: AH = 0
- -------------------------------------------------------------------------------
-
- This function loads the debug registers with the values in the array.
-
- 4.5 8259A Interrupt Vector Mapping Calls
-
- The default PC interrupt vector assignments for hardware interrupts are
- vectors 08h - 0Fh for interrupts IRQ0 - IRQ7, and vectors 70h - 77h for
- interrupts IRQ8 - IRQ15. The 80386 processor uses interrupt vectors 08h - 0Fh
- for processor exceptions, which are important to 386-specific software.
- Therefore, some clients find it desirable to reprogram the 8259A interrupt
- controller to map the hardware interrupt vectors elsewhere in the interrupt
- space. The server, as the first control program in place, is the repository
- of information on what the current vector mappings are. Client programs
- should query the server during initialization to determine the current
- mappings. If they have been changed from the PC default mappings, the client
- is obligated not to change them again. If they are still set to the PC
- defaults, the client can reprogram the interrupt controller and then inform
- the server what the new mappings are.
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 10
-
- ===============================================================================
- INT 67h
- AX = DE0Ah Get 8259A Interrupt Vector Mappings
- ===============================================================================
- INPUTS: None
- -------------------------------------------------------------------------------
- OUTPUTS: AH = 0
- BX = 1st vector mapping for master 8259A (IRQ0-IRQ7)
- CX = 1st vector mapping for slave 8259A (IRQ8-IRQ15)
- -------------------------------------------------------------------------------
-
- This function returns the interrupt vectors generated by the 8259A interrupt
- controller chips when a hardware interrupt occurs. If there is no slave 8259A
- to generate IRQ8-IRQ15 (because the software is running on a 386 accelerator
- card plugged into a PC or a PC/XT), then the value returned in CX is
- unspecified.
-
- Note that, for programs who wish to take over hardware interrupts in V86 mode,
- other considerations may apply when executing in a multitasking environment.
-
- ===============================================================================
- INT 67h
- AX = DE0Bh Set 8259A Interrupt Vector Mappings
- ===============================================================================
-
- INPUTS: BX = vector mapping for master 8259A (IRQ0-IRQ7)
- CX = vector mapping for slave 8259A (IRQ8-IRQ15)
- Interrupts disabled
- -------------------------------------------------------------------------------
- OUTPUTS: AH = 0
- -------------------------------------------------------------------------------
-
- This call is used by the client to inform the server if it remaps the 8259A
- interrupt controllers. The client must leave interrupts disabled from the
- time it begins to reprogram the interrupt controllers until after it makes
- this function call to inform the server of the remapping.
-
- Note that the server must leave interrupts disabled until after it has logged
- the vector mappings provided by the call. In particular, it must not
- "reflect" the interrupt back to V86 mode before recording the information, in
- case there is another program in the INT 67h chain which enables interrupts.
-
- If the client remaps the 8259A interrupt controller, it is responsible for
- restoring the original interrupt controller mappings when it terminates.
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 11
-
- 4.6 Switch to Protected Mode
-
- ===============================================================================
- INT 67h
- AX = DE0Ch Switch From V86 Mode to Protected Mode
- ===============================================================================
- INPUTS: ESI = linear address of data structure in first megabyte,
- containing values to load into system registers
- Interrupts disabled
- -------------------------------------------------------------------------------
- OUTPUTS: GDTR, IDTR, LDTR, TR loaded
- Interrupts disabled
- Control transferred to specified FAR entry point
- SS:ESP must have at least 16 BYTEs of space on it, and the
- protected mode entry point is required to set up its
- own stack before re-enabling interrupts
- EAX = contents modified
- ESI = contents modified
- DS, ES, FS, GS = contents modified
- All other registers unmodified
- -------------------------------------------------------------------------------
-
- This call switches to protected mode, sets up all the system tables for the
- client, and transfers control to the specified entry point in the client.
- Interrupts must remain disabled for the entire duration of the switch. The
- ESI register contains a linear address of a data structure in the first
- megabyte; because the page table mappings for the first megabyte are identical
- in both the server's and the client's page tables, this address can be used by
- the server both before and after reloading the CR3 register.
-
- The data structure pointed to by ESI looks like:
-
- 10 (DWORD) CS:EIP too transfer control to
- 0E (WORD) selector value to load into TR
- 0C (WORD) selector value to load into LDTR
- 08 (DWORD) linear address in first megabyte of 6-byte value to
- load into IDTR
- 04 (DWORD) linear address in first megabyte of 6-byte value to
- load into GDTR
- ESI->00 (DWORD) new value to load into CR3
-
- Note that the server must load GDTR before loading the LDTR and TR (IDTR can
- be loaded at any time, since interrupts are disabled). The GDTR and IDTR must
- be loaded with the 32-bit forms of the LGDT and LIDT instructions, not the 24-
- bit forms provided for backward compatibility with the 80286 processor. The
- server must clear the task busy bit in the TSS descriptor table entry in the
- client's GDT before loading TR (which must be loaded with an LTR instruction,
- not a task switch). Note that, since the client's GDT could reside anywhere
- in the 4 GB linear address space, the TSS descriptor table entry cannot be
- modified (and the LDTR and TR registers cannot be loaded) until after CR3 is
- loaded with the client's value, and the data segment used to modify the TSS
- descriptor must have a base address of zero and a limit of 4 GB. The server
- must not reload any segment registers after it loads the GDTR with the
- client's GDT address; note that the ability to modify GDTR and LDTR without
- reloading segment registers relies on the segment descriptor caching performed
- by the processor.
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 12
-
- The server's code that implements the switch must reside in the linear region
- that was initialized with the Get Protected Mode Interface call (function
- DE01h), since that is the only linear region that is mapped identically in
- both the server's and the client's page tables.
-
- When the client gets control, the stack is still set to whatever stack the
- server was using (because SS has not been reloaded, the descriptor cache
- register for SS still points to the server's stack segment). The client must
- reload all segment registers and set up its own stack before enabling
- interrupts. This is a requirement since an interrupt handler will attempt to
- save and restore segment registers, and the values left in the segment
- registers after the switch are not necessarily valid segments for the client.
-
- 5.0 Protected Mode Interface
-
- The protected mode interface is a FAR entry point in the server, which is
- obtained during initialization with the Get Protected Mode Interface system
- call (INT 67h function DE01h). The client makes a FAR call to a USE32 segment
- when it calls the server entry point, and the server must execute a USE32 FAR
- return when it terminates.
-
- An EMS function code of DEh is passed in AH, and a VCPI function code is
- passed in AL. If the function succeeds, AH is returned as zero; otherwise,
- there is an error code in AH. Except as noted for each call, all other
- registers are unchanged on output.
-
- If an undefined VCPI subfunction code is passed in AL, the server returns an
- error code in AH; the recommended value is 8Fh (bad subfunction code).
-
- 5.1 Memory Allocation Calls
-
- The memory allocation calls are used to allocate and free 4K pages of memory
- the server allocates these pages out of its expanded memory pool. The client
- can also do its own allocation of extended memory or XMS memory, if any is
- available.
-
- ===============================================================================
- INT 67h
- AX = DE03h Get Number of Free 4K Pages
- ===============================================================================
- INPUTS: None
- -------------------------------------------------------------------------------
- OUTPUTS: AH = 0
- EDX = number of free 4K pages
- -------------------------------------------------------------------------------
-
- This call returns the total number of 4K pages available to be allocated out
- of the server's expanded memory pool.
-
- Note that this is the total amount of free memory available to all tasks on
- the system. The client should allocate this memory only on an as needed
- basis. In addition, in a multitasking environment, this number does not
- reflect any memory restrictions placed on the client task by the multitasker.
- The client should, during initialization, use the EMS call Get Number of Pages
- (INT 67h function 3 (AH = 42h)) to obtain the number of unallocated EMS pages
- available, and then limit its usage of memory allocated through the server to
- that amount. (Note that the size of an EMS page is 16K, and the size of a
- page allocated through the VCPI interface is 4K.)
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 13
-
- ===============================================================================
- INT 67h
- AX = DE04h Allocate a 4K page
- ===============================================================================
- INPUTS: None
- -------------------------------------------------------------------------------
- OUTPUTS: If success:
- AH = 0
- EDX = PHYSICAL address of allocated 4K page
- If failure:
- AH = nonzero (recommended value: 88h)
- EDX = contents modified
- -------------------------------------------------------------------------------
-
- This call allocates a 4K page of memory. For backward compatibility, both the
- server and client must mask the 12 LSBs of the physical page address (returned
- in EDX) to zero. The client is responsible for freeing all memory allocated
- with this call before terminating execution.
-
-
- ===============================================================================
- INT 67h
- AX = DE05h Free a 4K Page
- ===============================================================================
- INPUTS: EDX = PHYSICAL address of allocated 4K page
- -------------------------------------------------------------------------------
- OUTPUTS: If success:
- AH = 0
- If failure:
- AH = nonzero (recommended value: 8Ah)
- -------------------------------------------------------------------------------
-
- This call frees a page of memory previously allocated with subfunction 04h.
- For backward compatibility, both the server and the client must mask the 12
- LSBs of the physical page address (passed in EDX) to zero.
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 14
-
- 5.2 Switch to V86 Mode
-
- ===============================================================================
- INT 67h
- AX = DE0Ch Switch From Protected Mode to V86 Mode
- ===============================================================================
- INPUTS: Top of stack looks as described below
- Interrupts disabled
- SS:ESP must be in the first megabyte of linear memory
- DS = segment selector that maps the entire linear address space
- that was obtained with subfunction 01h, Get Protected Mode
- Interface (i.e., its base address is 0, and its limit is
- the size of the address space obtained with the Get
- Protected Mode Interface call)
- -------------------------------------------------------------------------------
- OUTPUTS: GDTR, IDTR, LDTR, TR loaded with server's values
- Interrupts disabled
- Control transferred to specified FAR entry point
- SS:ESP and all segment registers loaded with values on stack
- EAX = destroyed
- All other registers unmodified
- -------------------------------------------------------------------------------
-
- This call switches from protected mode back to V86 mode, after setting up all
- of the server's system tables. The top of stack looks as follows on input to
- this function:
-
- 28 (DWORD) GS value
- 24 (DWORD) FS value
- 20 (DWORD) DS value
- 1C (DWORD) ES value
- 18 (DWORD) SS value
- 14 (DWORD) ESP value
- 10 (DWORD) reserved for EFLAGS value
- 0C (DWORD) CS value
- 08 (DWORD) EIP value
- SS:ESP-> 00 (DWORD) return address from FAR call to USE32 segment
-
- The first 8 bytes at SS:ESP are the return address pushed by the FAR CAlL
- instruction; since this call never returns, the return address is irrelevant
- and should be discarded. It is the responsibility of the server to fill in an
- appropriate EFLAGS value (e.g., VM bit set, IOPL = 3, IF bit cleared) before
- executing the IRETD to return to V86 mode. Interrupts must remain disabled
- for the entire duration of the switch, and the interrupt enable bit must be
- off in the EFLAGS value which is stored on the stack before executing the
- IRETD which switches back to V86 mode. The server's code that implements the
- switch must reside in the linear region that was initialized with the Get
- Protected Mode Interface call (function DE01h), since that is the only linear
- region that is mapped identically in both the server's and the client's page
- tables.
-
- If the client does any task switching, it should clear the TS bit in CR0
- before making this call. Otherwise, the TS bit will still be set after the
- switch to V86 mode, and a floating point coprocessor instruction in V86 mode
- will cause an exception 7 trap to the server.
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 15
-
- Appendix A
-
- Implementation Notes
-
- A.1 Top-Down Extended Memory Allocation
-
- The BIOS extended memory size system call is used to determine the upper limit
- of extended memory which is not in use by other programs. The following code
- fragment gets the physical address of one byte past the end of available
- extended memory in the EAX register:
-
- xor eax,eax ; clear MSBs in EAX
- mov ah, 88h ; get size of extended memory in KB
- int 15h
- shl eax, 10 ; convert it address of top of memory
- add eax, 100000h
-
- To allocate extended memory top down, simply install an INT 15h handler which
- passes all functions except 88h through to the previous INT 15h handler. If
- an INT 15h function 88h call is made, return a value which reduces the size of
- extended memory by the amount of memory you wish to allocate.
-
- A.2 Bottom-Up Extended Memory Allocation
-
- Bottom-up extended memory allocation is not recommended, as it is more
- complicated and less versatile than top-down allocation. However, programs
- that wish to allocate extended memory must first check to see if any other
- programs have allocated extended memory using the bottom-up technique. Bottom-
- up extended memory allocation is done by marking the amount of memory
- allocated in two locations. If there is any extended memory on the system (if
- the BIOS call documented in Appendix A.1 does not return zero), it is
- necessary to check BOTH of these locations to see if any bottom-up extended
- memory has been allocated. If the two locations show different amounts of
- allocated memory, the safest thing to do is terminate with an error message.
- Failing that, the larger of the two values found should be used. The values
- may differ in the two locations because there are several programs available
- which use bottom-up allocation but which do not correctly update both
- locations, and also because the DOS PRINT command in DOS 3.3 or later wipes
- out the allocation information in one of the two locations.
-
- The first location is the segment pointed at by the INT 19h vector (the reboot
- interrupt). If an appropriate signature is present at a specific offset in
- this segment, then there is a 24-bit address of the first free byte of
- extended memory at another specific offset in the segment. The following code
- fragment obtains the physical address of the first free byte of extended
- memory and loads it into EAX:
-
- data segment
- vdisk_sig db 'VDISK V' ; signature string
- SIG _ LEN equ $ - vdisk_sig ; signature string length
- SIG_VEC equ 19h ; interrupt vector for signature
- SIG_OFFS equ 12h ; offset of signature string in segment
- LO_OFFS equ 2Ch ; offset of low word of 24-bit value
- HI_OFFS equ 2Eh ; offset of high byte of 24-bit value
- data ends
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 16
-
- assume cs:code,ds:data
- code segment use16
-
- xor ax,ax ; get segment addr in ES
- mov es,ax
- mov ax,es:(SIG_VEC * 4) + 2
- mov es,ax
-
- mov di,SIG_OFFS ; branch of signature not present
- lea si,vdisk_sig
- mov ex,SIG_LEN
- cld
- repe cmpsb
- jne short no_alloc
-
- xor eax,eax ; get addr of bottom of extended memory
- mov al,es:HI_OFFS ; into EAX
- shl eax,16
- mov ax,es:LO_OFFS
- jmp short done ; all done
-
- no_alloc:
- mov eax,100000h ; no bottom-up memory allocated
-
- done: ; bottom of extended memory is now in EAX
- code ends
-
- The second location to check is a boot block located at one megabyte. The
- following C code fragment retrieves the allocation value from the boot block
- and saves it in the variable "bot_ext" (note that this code should NOT be
- executed if there is no extended memory on the system, since it attempts to
- read memory at one megabyte):
-
- long bot_ext; /* addr of 1st free byte of extended memory */
- char buf [0x20]; /* buffers boot block */
- #define SIGOFF 0x03 /* offset of signature in boot block */
- #define SIZEOFF 0x1E /* offset of size word in boot block */
-
- /*
- * Read boot block at one megabyte by calling an assembly language
- * routine (not shown) which either uses the BIOS block move call to
- * read from extended memory, or does it in some other way.
- */
-
- read_ext(0x100000, buf, sizeof(buf));
-
- /*
- * Now check for the correct signature in the boot block, and if
- * present, extract the bottom of available extended memory.
- */
-
- if (memcmp(&buf[SIGOFF], "VDISK", 5) != 0)
- bot_ext = 0x100000;
- else
- {
- bot_ext = 01;
- memcpy(&bot_ext, &buf[SIZEOFF], 2]; /* get KB addr */
- bot_ext = bot_ext << 10; /* convert to byte addr */
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 17
-
- A.3 Sample VCPI Detection Code
-
- The following code sequence should be used to detect the presence of the VCPI
- interface:
-
- data segment
- emm_name db 'EMMXXXX0',0 ; device name for EMM
- data ends
-
- assume cs:code,ds:data
- code segment use16
- ;
- ; First check to make sure we are on an 80386 or 80486
- ;
- pushf ; save flags
- xor ax,ax ; try to put a zero word into flags and then
- push ax ; get result back into AX
- popf
- pushf
- pop ax
- and ax,0F000h ; if high 4 bits of flags are all 1's, it's an
- cmp ax,0F000h ; 8086/8088/80186/80188
- jne short not_386
- mov ax,0F000h ; Now try to set the high 4 bits of the flags
- push ax ; and then get the result back in AX
- popf
- pushf
- pop ax
- and ax,0F000h ; if none of the high 4 bits are set, it's an
- jz short not_386 ; 80286 -- otherwise, it's a 386 or 486
- popf ; restore flags
- jmp short ems_check ; go to next check
- not_386:
- popf ; restore flags
- jmp no_vcpi ; not a 386 or 486 -- VCPI not present
-
- ems_check:
- ;
- ; Check for EMS driver present
- ;
- lea dx,emm_name ; open EMM device, read-only
- mov ax,3D00h
- int 21h
- jc short no_vcpi ; branch if error
- mov bx,ax ; get device information
- mov ax,4400h
- int 21h
- jc short no_vcpi ; branch if error
- test dx,80h ; branch if file (not device)
- jz short no_vcpi
- mov ax,4407h ; check output status
- int 21h
- push ax ; save return code from IOCTL call
- mov ah,3Eh ; close file
- int 21h
- pop ax ; restore IOCTL return code
- cmp al,0FFh ; branch if status not device ready
- jne short no_vcpi
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 18
-
- ; Now allocate an EMS page to make sure the EMS emulator is turned on.
- ; Note that we must save the handle for this allocated page and free it
- ; again eventually, although this is not shown in the code fragment.
- ;
- mov bx,1 ; allocate 1 EMS page
- mov ah,43h
- int 67h
- cmp ah,0 ; branch if error
- jne short no_vcpi
- ; save handle returned in DX to be freed later
-
- ; Now make VCPI detection call
- ;
- mov ax,0DE00h ; is VCPI there?
- int 67h
- cmp ah,0 ; branch if not there
- jne short no_vcpi
- ; OK, the VCPI interface is present and the server is turned on.
- no_vcpi: ; VCPI interface not present
- code ends
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 19
-
-
- GLOSSARY
-
- 4K page A four-kilobyte page, the page size allocated by
- calls to the VCPI interface. A 4K page is always
- aligned on a four-kilobyte physical address boundary.
-
- A20 Address line 20. On AT and MCA architectures, there
- is hardware to truncate physical addresses to 20 bits
- (one megabyte). This is known as "disabling A20," and
- is for compatibility with 8086 programs which rely on
- address wraparound at one megabyte. To use extended
- memory, it is necessary to "enable A20."
-
- bottom-up allocation Allocation of extended memory starting at one
- megabyte and growing upward. This allocation method
- is used by older VDISK device drivers.
-
- client A program which uses the VCPI interface
-
- expanded memory Memory allocated by an EMS emulator
-
- extended memory Physical memory above one megabyte.
-
- EMS page A 16-kilobyte page, the page size allocated by calls
- to an EMS driver. An EMS page is always allocated on
- a four-kilobyte physical address boundary.
-
- real mode address space Linear addresses below one megabyte (note that this
- does not necessarily correspond to physical addresses
- below one megabyte)
-
- server A program which provides the VCPI interface
-
- top-down allocation Allocation of extended memory starting at the top of
- memory and growing downward. This is the recommended
- technique for allocating extended memory.
-
- ______________________________________________________________________________
- VCPI Version 1.0 June 12, 1989 Page 20